package com.ly.heart.service.impl;

import java.util.List;
import java.util.Optional;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.ly.common.core.domain.AjaxResult;
import com.ly.common.core.domain.entity.SysDept;
import com.ly.common.core.domain.entity.SysUser;
import com.ly.common.exception.CustomException;
import com.ly.common.utils.DateUtils;
import com.ly.common.utils.SecurityUtils;
import com.ly.common.utils.StringUtils;
import com.ly.common.utils.erp.ConstUtil;
import com.ly.common.utils.erp.SnowflakeIdWorker;
import com.ly.heart.domain.*;
import com.ly.heart.domain.dto.KingInvoiceReceivableOtherDto;
import com.ly.heart.domain.dto.StartProcessDto;
import com.ly.common.core.domain.ActCurrentTaskVo;
import com.ly.heart.domain.vo.KingInvoiceReceivableOtherVo;
import com.ly.heart.mapper.KingInvoiceReceivableOtherMapper;
import com.ly.heart.service.*;
import com.ly.system.service.ISysDeptService;
import com.ly.system.service.ISysUserService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;

/**
 * 金蝶-财务-其他应收单Service业务层处理
 * @author wutao
 * @date 2024-07-19
 */
@Service
public class KingInvoiceReceivableOtherServiceImpl extends ServiceImpl<KingInvoiceReceivableOtherMapper, KingInvoiceReceivableOtherEntity> implements IKingInvoiceReceivableOtherService {

    @Resource
    private KingInvoiceReceivableOtherMapper kingInvoiceReceivableOtherEntityMapper;
    @Resource
    private IKingInvoicePayableReceivableOtherDetailService iKingInvoicePayableReceivableOtherDetailService;
    @Resource
    private IActModelService iActModelService;
    @Resource
    private IActTaskCommentService iActTaskCommentService;
    @Resource
    private ICustomerService iCustomerService;
    @Resource
    private ISupplierService iSupplierService;
    @Resource
    private ISysDeptService iSysDeptService;
    @Resource
    private ISysUserService iSysUserService;
    @Resource
    private IKingBaseTransactionsCompanyService iKingBaseTransactionsCompanyService;

    /**
     * 查询金蝶-财务-其他应收单
     * @param id 金蝶-财务-其他应收单ID
     * @return 金蝶-财务-其他应收单
     */
    @Override
    public KingInvoiceReceivableOtherVo selectKingInvoiceReceivableOtherEntityById (String id) {
        KingInvoiceReceivableOtherVo vo = new KingInvoiceReceivableOtherVo ();
        KingInvoiceReceivableOtherEntity receivableOtherEntity = kingInvoiceReceivableOtherEntityMapper.selectKingInvoiceReceivableOtherEntityById ( id );
        String transactionCompanyName = getCompanyName ( receivableOtherEntity.getTransactionCompanyType (), receivableOtherEntity.getTransactionCompanyId () );
        receivableOtherEntity.setTransactionCompanyName ( transactionCompanyName );
        KingInvoicePayableReceivableOtherDetailEntity payableReceivableOtherDetailEntity = new KingInvoicePayableReceivableOtherDetailEntity ();
        payableReceivableOtherDetailEntity.setRelationOtherId ( id );
        List<KingInvoicePayableReceivableOtherDetailEntity> kingInvoicePayableReceivableOtherDetailEntities = iKingInvoicePayableReceivableOtherDetailService.selectKingInvoicePayableReceivableOtherDetailEntityList ( payableReceivableOtherDetailEntity );
        vo.setKingInvoiceReceivableOtherEntity ( receivableOtherEntity ).setKingInvoicePayableReceivableOtherDetailEntities ( kingInvoicePayableReceivableOtherDetailEntities );
        return vo;
    }

    /**
     * 查询金蝶-财务-其他应收单列表
     * @param kingInvoiceReceivableOtherEntity 金蝶-财务-其他应收单
     * @return 金蝶-财务-其他应收单
     */
    @Override
    public List<KingInvoiceReceivableOtherEntity> selectKingInvoiceReceivableOtherEntityList (KingInvoiceReceivableOtherEntity kingInvoiceReceivableOtherEntity) {
        kingInvoiceReceivableOtherEntity.setIsUsed ( ConstUtil.IS_USED_YES );
        kingInvoiceReceivableOtherEntity.setPage ( ( kingInvoiceReceivableOtherEntity.getPage () - 1 ) * kingInvoiceReceivableOtherEntity.getLimit () );
        List<KingInvoiceReceivableOtherEntity> kingInvoiceReceivableOtherEntities = kingInvoiceReceivableOtherEntityMapper.selectKingInvoiceReceivableOtherEntityList ( kingInvoiceReceivableOtherEntity );
        kingInvoiceReceivableOtherEntities.forEach ( receivableOther -> {
            String transactionCompanyName = getCompanyName ( receivableOther.getTransactionCompanyType (), receivableOther.getTransactionCompanyId () );
            receivableOther.setTransactionCompanyName ( transactionCompanyName );
            //处理最后一个审批人
            ActTaskCommentEntity actTaskCommentEntity = iActTaskCommentService.queryLastComment ( receivableOther.getInstanceId () );
            if ( actTaskCommentEntity != null ) {
                receivableOther.setApprovedUser ( actTaskCommentEntity.getApprovedUser () );
                receivableOther.setApprovedRemark ( actTaskCommentEntity.getRemark () );
            }
            //任务信息
            ActCurrentTaskVo currentTaskVo = iActModelService.getCurrentTaskByInstanceId ( receivableOther.getInstanceId () );
            Optional.ofNullable ( currentTaskVo ).ifPresent ( currentTask -> {
                receivableOther.setCurrentTask ( currentTask );
            } );
        } );
        return kingInvoiceReceivableOtherEntities;
    }

    @Override
    public Integer queryCount (KingInvoiceReceivableOtherEntity kingInvoiceReceivableOtherEntity) {
        Integer count = kingInvoiceReceivableOtherEntityMapper.queryCount ( kingInvoiceReceivableOtherEntity );
        return count;
    }

    @Override
    public KingInvoiceReceivableOtherEntity querySingleById (String id) {
        KingInvoiceReceivableOtherEntity kingInvoiceReceivableOtherEntity = kingInvoiceReceivableOtherEntityMapper.querySingleById ( id );
        return kingInvoiceReceivableOtherEntity;
    }

    /**
     * 新增金蝶-财务-其他应收单
     * @param kingInvoiceReceivableOtherDto 金蝶-财务-其他应收单
     * @return 结果
     */
    @Override
    public AjaxResult draft (KingInvoiceReceivableOtherDto kingInvoiceReceivableOtherDto) {
        KingInvoiceReceivableOtherEntity kingInvoiceReceivableOtherEntity = kingInvoiceReceivableOtherDto.getKingInvoiceReceivableOtherEntity ();
        kingInvoiceReceivableOtherEntity.setId ( SnowflakeIdWorker.getInstance ().nextStringId () );
        int count = this.count ();
        kingInvoiceReceivableOtherEntity.setDocNo ( "QTYSD".concat ( String.format ( "%08d", count ) ) );
        kingInvoiceReceivableOtherEntity.setCreateBy ( SecurityUtils.getLoginUser ().getUser ().getUserId () );
        kingInvoiceReceivableOtherEntity.setCreateTime ( DateUtils.getNowDate () );
        updateReceivableOtherDetail ( kingInvoiceReceivableOtherDto.getKingInvoicePayableReceivableOtherDetailEntities (), kingInvoiceReceivableOtherEntity.getId () );
        kingInvoiceReceivableOtherEntity.setState ( ConstUtil.STATE_IN_DRAFT );
        boolean save = this.save ( kingInvoiceReceivableOtherEntity );
        if ( ! save ) {
            throw new CustomException ( "新增其他应收单失败！" );
        }
        return AjaxResult.success ( "新增其他应收单成功", kingInvoiceReceivableOtherEntity.getId () );
    }

    @Override
    public AjaxResult submit (KingInvoiceReceivableOtherEntity kingInvoiceReceivableOtherEntity) {
        if ( StringUtils.isBlank ( kingInvoiceReceivableOtherEntity.getId () ) ) {
            return AjaxResult.error ( "请先暂存该单据！" );
        }
        StartProcessDto startDto = new StartProcessDto ().
                setBusinessId ( kingInvoiceReceivableOtherEntity.getId () ).
                setBusinessType ( kingInvoiceReceivableOtherEntity.getBusinessType () ).setModelId ( kingInvoiceReceivableOtherEntity.getModelId () ).
                setBusinessName ( "其他应收单_".concat ( kingInvoiceReceivableOtherEntity.getId () ) );
        String instanceId = iActModelService.startProcess ( startDto );
        boolean update = this.update ( new LambdaUpdateWrapper<KingInvoiceReceivableOtherEntity> ().
                set ( KingInvoiceReceivableOtherEntity :: getState, ConstUtil.STATE_IN_PROCESS ).
                set ( KingInvoiceReceivableOtherEntity :: getInstanceId, instanceId ).
                eq ( KingInvoiceReceivableOtherEntity :: getId, kingInvoiceReceivableOtherEntity.getId () ) );
        if ( ! update ) {
            throw new CustomException ( "提交其他应收单失败！" );
        }
        return AjaxResult.success ( "提交其他应收单成功" );
    }

    /**
     * 修改金蝶-财务-其他应收单
     * @param kingInvoiceReceivableOtherDto 金蝶-财务-其他应收单
     * @return 结果
     */
    @Override
    public AjaxResult updateKingInvoiceReceivableOtherEntity (KingInvoiceReceivableOtherDto kingInvoiceReceivableOtherDto) {
        KingInvoiceReceivableOtherEntity kingInvoiceReceivableOtherEntity = kingInvoiceReceivableOtherDto.getKingInvoiceReceivableOtherEntity ();
        kingInvoiceReceivableOtherEntity.setUpdateBy ( SecurityUtils.getLoginUser ().getUser ().getUserId () );
        kingInvoiceReceivableOtherEntity.setUpdateTime ( DateUtils.getNowDate () );
        updateReceivableOtherDetail ( kingInvoiceReceivableOtherDto.getKingInvoicePayableReceivableOtherDetailEntities (), kingInvoiceReceivableOtherEntity.getId () );
        boolean b = this.updateById ( kingInvoiceReceivableOtherEntity );
        if ( ! b ) {
            throw new CustomException ( "修改其他应收单失败！" );
        }
        return AjaxResult.success ( "修改其他应收单成功" );
    }

    /**
     * 批量删除金蝶-财务-其他应收单
     * @param ids 需要删除的金蝶-财务-其他应收单ID
     * @return 结果
     */
    @Override
    public AjaxResult deleteKingInvoiceReceivableOtherEntityByIds (String[] ids) {
        boolean update = this.update ( new LambdaUpdateWrapper<KingInvoiceReceivableOtherEntity> ().
                set ( KingInvoiceReceivableOtherEntity :: getIsUsed, ConstUtil.IS_USED_NO ).
                in ( KingInvoiceReceivableOtherEntity :: getId, ids ) );
        if ( ! update ) {
            throw new CustomException ( "删除其他应收单失败！" );
        }
        return AjaxResult.success ( "删除其他应收单成功" );
    }


    private void updateReceivableOtherDetail (List<KingInvoicePayableReceivableOtherDetailEntity> payableReceivableOtherDetailEntities, String relationId) {
        if ( ! CollectionUtils.isEmpty ( payableReceivableOtherDetailEntities ) ) {
            iKingInvoicePayableReceivableOtherDetailService.remove ( new LambdaUpdateWrapper<KingInvoicePayableReceivableOtherDetailEntity> ().
                    eq ( KingInvoicePayableReceivableOtherDetailEntity :: getRelationOtherId, relationId ).
                    eq ( KingInvoicePayableReceivableOtherDetailEntity :: getType, 2 ) );
            payableReceivableOtherDetailEntities.forEach ( detail -> {
                detail.setRelationOtherId ( relationId );
                detail.setType ( 2 );
                iKingInvoicePayableReceivableOtherDetailService.insertKingInvoicePayableReceivableOtherDetailEntity ( detail );
            } );
        }
    }

    /**
     * 根据往来单位类型，获取往来单位和付款单位
     * @param companyType：单位类型，根据往来单位或付款单位的类型魔法值
     * @param companyId：单位Id，根据单位类型，选择的具体单位Id
     * @return
     */
    private String getCompanyName (String companyType, String companyId) {
        if ( StringUtils.isBlank ( companyType ) || StringUtils.isBlank ( companyId ) ) {
            return "";
        }
        String transactionCompany = "";
        switch ( companyType ) {
            case "BD_Customer":
                CustomerEntity customerEntity = iCustomerService.getById ( companyId );
                if ( customerEntity != null )
                    transactionCompany = customerEntity.getCustomerName ();
                break;
            case "BD_Supplier":
                SupplierEntity supplierEntity = iSupplierService.getById ( companyId );
                if ( supplierEntity != null )
                    transactionCompany = supplierEntity.getSupplierName ();
                break;
            case "BD_Department":
                SysDept sysDept = iSysDeptService.getById ( companyId );
                if ( sysDept != null )
                    transactionCompany = sysDept.getDeptName ();
                break;
            case "BD_Empinfo":
                SysUser sysUser = iSysUserService.getById ( companyId );
                if ( sysUser != null )
                    transactionCompany = sysUser.getNickName ();
                break;
            case "FIN_OTHERS":
                KingBaseTransactionsCompanyEntity transactionsCompanyEntity = iKingBaseTransactionsCompanyService.getById ( companyId );
                if ( transactionsCompanyEntity != null )
                    transactionCompany = transactionsCompanyEntity.getTitle ();
                break;
        }
        return transactionCompany;
    }
}
